#ifndef AVALON_CHANNELADAPTERSERVERCONNECTION_HPP
#define AVALON_CHANNELADAPTERSERVERCONNECTION_HPP
#include <boost/functional/factory.hpp>
#include "Avalon/IO/ConnectionState.hpp"
#include "Avalon/IO/ServerConnection.hpp"

namespace Avalon {
namespace IO {

  /*! \class ChannelAdapterServerConnection
   *  \brief Adapter class for a ServerConnection requiring a specific Channel.
   */
  class ChannelAdapterServerConnection : public ServerConnection {
    public:

      //! Constructs a ChannelAdapterServerConnection.
      /*!
        \param connection The ServerConnection to wrap.
        \param channelFactory The ChannelFactory to use to build new incoming
                              Channels.
      */
      ChannelAdapterServerConnection(ServerConnection* connection,
        ChannelFactory* channelFactory);

      virtual ~ChannelAdapterServerConnection();

      virtual void Open();

      virtual void Accept(Out<Threading::Async<Channel*> > channel);

      virtual bool IsOpen() const;

      virtual void Close();

      virtual void SetClosedSlot(const ClosedSlot& slot, Out<bool> isOpen);

    private:
      boost::scoped_ptr<ServerConnection> m_connection;
      boost::scoped_ptr<ChannelFactory> m_channelFactory;
      Threading::Async<Channel*> m_result;
      Threading::Async<Channel*>* m_wrappedChannel;
      Threading::Async<Channel*>::FinishedSlot m_acceptSlot;

      void OnAccept();
  };
}
}

#endif // AVALON_CHANNELADAPTERSERVERCONNECTION_HPP
